//
//  MOFormDescription.m
//  MOED, Version 1.0
//
//  http://moed.googlecode.com/
//
//  Copyright (c) 2011, Eternity Technologies.
//  All rights reserved.
// 
//  Redistribution and use in source and binary forms, with or without
//  modification, are permitted provided that the following conditions are met:
//
//    * Redistributions of source code must retain the above copyright
//      notice, this list of conditions and the following disclaimer.
//    * Redistributions in binary form must reproduce the above copyright
//      notice, this list of conditions and the following disclaimer in the
//      documentation and/or other materials provided with the distribution.
//    * Neither the name of the Eternity Technologies nor the
//      names of its contributors may be used to endorse or promote products
//      derived from this software without specific prior written permission.
//
//  THIS SOFTWARE IS PROVIDED BY ETERNITY TECHNOLOGIES ''AS IS'' AND ANY
//  EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
//  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
//  DISCLAIMED. IN NO EVENT SHALL ETERNITY TECHNOLOGIES BE LIABLE FOR ANY
//  DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
//  (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
//  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
//  ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
//  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
//  SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//

#import "MOFormDescription.h"
#import "JSON.h"

#import "MOFormSection.h"
#import "MOFormField.h"
#import "MOFormTableViewDescription.h"

@implementation MOFormDescription

@synthesize formName;
@synthesize modelName;
@synthesize useLocalizedStrings;
@synthesize formSections;
@synthesize tableViewDescription;

- (id) initWithFormDescriptionFilename:(NSString *) filename {
	self = [super init];
	if(self) {
		
		formName = nil;
		modelName = nil;
		useLocalizedStrings = NO;
		formSections = nil;

		[self loadFormDescription:filename];
		NSLog(@"[MOFormDescription/%@/Ready] Has %i section(s)", self.formName, [formSections count]);

	}
	return self;
}

- (void) dealloc {
	[formName release];
	[modelName release];
	[tableViewDescription release];
	[formSections release];
	[super dealloc];
}

- (void) loadFormDescription:(NSString *) fileName {
	
	NSError *stringError;
	/* Read contents of JSON file as String */
	NSString *formDescriptorJSON = [[NSString alloc] initWithContentsOfFile:[[NSBundle mainBundle] pathForResource:fileName
																											ofType:@"json"]
																   encoding:NSUTF8StringEncoding 
																	  error:&stringError];
	
	NSError *jsonParseError;
	/* Try and parse the JSON */
	SBJsonParser *jsonParser = [[SBJsonParser alloc] init];
	id jsonObject = [[jsonParser objectWithString:formDescriptorJSON error:&jsonParseError] retain];
	[jsonParser release];
	[formDescriptorJSON release];

	/* Release if previously allocated */
	[formName release];
	[modelName release];
	[formSections release];

	formName = [jsonObject valueForKey:@"formName"] != [NSNull null] ? [[jsonObject valueForKey:@"formName"] copy]:nil;
	modelName = [jsonObject valueForKey:@"managedModelName"] != [NSNull null] ? [[jsonObject valueForKey:@"managedModelName"] copy]:nil;
	useLocalizedStrings = [jsonObject valueForKey:@"useLocalizedStrings"] != [NSNull null] ? [[jsonObject valueForKey:@"useLocalizedStrings"] boolValue]:NO;
	tableViewDescription = [jsonObject valueForKey:@"tableViewDescription"] ? [[MOFormTableViewDescription alloc] initWithJSON:[jsonObject valueForKey:@"tableViewDescription"]]:nil;

	NSMutableArray *parsedSections = [[NSMutableArray alloc] init];
	
	NSInteger tag = 1;
	
	MOFormSection *formSection = nil;
	for(id sectionJSON in [jsonObject valueForKey:@"sections"]) {
		formSection = [[MOFormSection alloc] initWithJSON:sectionJSON tag:tag];
		formSection.useLocalizedStrings = self.useLocalizedStrings;
		[parsedSections addObject:formSection];
		[formSection release];
		
		/* Restore the tag value from the section */
		tag = formSection.tag;
	}
	
	formSections = [[NSArray alloc] initWithArray:parsedSections];
	[parsedSections release];
	
	[jsonObject release];
	
}


#pragma mark -
#pragma mark Helpers for Form Description

- (NSIndexPath *) indexPathForTag:(NSInteger) tag {
	for(NSInteger sectionIndex = 0; sectionIndex < [formSections count]; sectionIndex++) {
		MOFormSection *fieldSection = [formSections objectAtIndex:sectionIndex];
		for(NSInteger fieldIndex = 0; fieldIndex < [fieldSection.fields count]; fieldIndex++) {
			MOFormField *field = [fieldSection.fields objectAtIndex:fieldIndex];
			if(field.tag == tag)
				return [NSIndexPath indexPathForRow:fieldIndex inSection:sectionIndex];
		}
	}
	return nil;
}

- (MOFormField *) fieldInformationForTag:(NSInteger) tag {
	for(MOFormSection *fieldSection in formSections) {
		for(MOFormField *field in fieldSection.fields) {
			if(field.tag == tag)
				return field;
		}
	}
	return nil;
}

- (NSInteger) numberOfSections {
	return [formSections count];
}

- (NSInteger) numberOfFieldsInSection:(NSInteger) sectionIndex {
	MOFormSection *section = [formSections objectAtIndex:sectionIndex];
	return [section.fields count];
}

- (MOFormSection *) formSectionAtIndex:(NSInteger) sectionIndex {
	return [formSections objectAtIndex:sectionIndex];
}

- (MOFormField *) formFieldAtIndexPath:(NSIndexPath *) indexPath {
	MOFormSection *formSection = [formSections objectAtIndex:indexPath.section];
	MOFormField *formField = [formSection.fields objectAtIndex:indexPath.row];
	return formField;
}

- (MOFormField *) formFieldAtTag:(NSInteger) tag {
	for(MOFormSection *formSection in formSections) {
		for(MOFormField *formField in formSection.fields) {
			if(formField.tag == tag) return formField;
		}
	}
	return nil;
}

#pragma mark -
#pragma mark Accessors

- (NSString *) formName {
	if(useLocalizedStrings) return NSLocalizedString(formName, @"");
	return formName;	
}

@end
